/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin			*/
/*	Project:	GlbCloud			*/
/*	Author:		gong_libin			*/
/*	Date:		2012_01_06			*/
/*	File:		MrConf.cpp			*/
/********************************************************/

#include "MrConf.h"

CMrConf::CMrConf()
{
	m_pstFile = NULL;
}

CMrConf::~CMrConf()
{
}

void CMrConf::MrConfClose()
{
	if (NULL != m_pstFile) {
		fclose(m_pstFile);
		m_pstFile = NULL;
	}

	return;
}

int CMrConf::MrConfOpen(char* pszFile)
{
	int iReturn = MR_SUCCESS;

	if (NULL == (m_pstFile = fopen(pszFile, "r"))) {
		MR_ERROR("%s\n", strerror(errno));
		iReturn = MR_ERR_OEN;
	}

	return iReturn;
}

int CMrConf::MrConfGetLine(char* pszLine, int iSize)
{
	int iReturn = MR_SUCCESS;

	if (NULL != m_pstFile) {
		if (NULL == fgets(pszLine, iSize, m_pstFile)) {
			iReturn = MR_ERR_OTH;
		}
	}
	else {
		iReturn = MR_ERR_OEN;
	}

	return iReturn;
}

int CMrConf::MrConfGetSec(char* pszSec)
{
	int iReturn = MR_ERR_SEC;
	char szLine[MR_PACKET] = { 0 };

	if (NULL != m_pstFile) {
		rewind(m_pstFile);
		while (MR_SUCCESS == MrConfGetLine(szLine, MR_PACKET - 1)) {
			if (true != MrConfIsValid(szLine)) continue;
			if (true == MrConfIsSection(szLine)) {
				if (MR_SUCCESS == strncasecmp(&szLine[1], pszSec, strlen(pszSec))) {
					iReturn = MR_SUCCESS;
					break;
				}
			}
			memset(szLine, '\0', MR_PACKET);
		}
	}
	else {
		iReturn = MR_ERR_OEN;
	}

	return iReturn;
}

int CMrConf::MrConfGetKey(char* pszSec, char* pszKey)
{
	bool bSec = false;
	int iReturn = MR_ERR_SEC;
	char szLine[MR_PACKET] = { 0 };

	if (NULL != m_pstFile) {
		rewind(m_pstFile);
		while (MR_SUCCESS == MrConfGetLine(szLine, MR_PACKET - 1)) {
			if (true != MrConfIsValid(szLine)) continue;
			if (true == MrConfIsSection(szLine)) {
				if (false == bSec) {
					if (MR_SUCCESS == strncasecmp(&szLine[1], pszSec, strlen(pszSec))) {
						iReturn = MR_ERR_KEY;
						bSec = true;
					}
				}
				else {
					bSec = false;
				}
			}
			else {
				if (true == bSec) {
					if (MR_SUCCESS == strncasecmp(szLine, pszKey, strlen(pszKey))) {
						iReturn = MR_SUCCESS;
						break;
					}
				}
			}
			memset(szLine, '\0', MR_PACKET);
		}
	}
	else {
		iReturn = MR_ERR_OEN;
	}

	return iReturn;
}

int CMrConf::MrConfGetVal(char* pszSec, char* pszKey, char* pszVal)
{
	bool bSec = false;
	int iReturn = MR_ERR_SEC;
	char szLine[MR_PACKET] = { 0 };

	if (NULL != m_pstFile) {
		rewind(m_pstFile);
		while (MR_SUCCESS == MrConfGetLine(szLine, MR_PACKET - 1)) {
			if (true != MrConfIsValid(szLine)) continue;
			if (true == MrConfIsSection(szLine)) {
				if (false == bSec) {
					if (MR_SUCCESS == strncasecmp(&szLine[1], pszSec, strlen(pszSec))) {
						iReturn = MR_ERR_KEY;
						bSec = true;
					}
				}
				else {
					bSec = false;
				}
			}
			else {
				if (true == bSec) {
					if (MR_SUCCESS == strncasecmp(szLine, pszKey, strlen(pszKey))) {
						iReturn = MR_ERR_VAL;
						MrConfTrimRight(szLine);
						if (MR_SUCCESS == MrConfKeyValue(szLine, pszKey, pszVal)) {
							iReturn = MR_SUCCESS;
						}
						break;
					}
				}
			}
			memset(szLine, '\0', MR_PACKET);
		}
	}
	else {
		iReturn = MR_ERR_OEN;
	}

	return iReturn;
}

int CMrConf::MrConfKeyValue(char* pszLine, char* pszKey, char* pszVal)
{
	char* pszCur = pszLine;
	int iReturn = MR_SUCCESS;
	int iLength = strlen(pszLine);

	while (pszCur - pszLine < iLength && MR_EQUAL != *pszCur) pszCur += 1;

	if (pszCur - pszLine != iLength) {
		*pszCur ++ = '\0';
		MrConfTrimLeft(pszCur);
		strcpy(pszVal, pszCur);
	}
	else {
		iReturn = MR_ERR_VAL;
	}

	return iReturn;
}

int CMrConf::MrConfKeyValue(char* pszLine, char** ppszKey, char** ppszVal)
{
	char* pszCur = pszLine;
	int iReturn = MR_SUCCESS;
	int iLength = strlen(pszLine);

	while (pszCur - pszLine < iLength && MR_EQUAL != *pszCur) pszCur += 1;

	if (pszCur - pszLine != iLength) {
		*pszCur ++ = '\0';
		MrConfTrimRight(pszLine);
		MrConfTrimLeft(pszCur);
		*ppszKey = pszLine;
		*ppszVal = pszCur;
	}
	else {
		iReturn = MR_ERR_VAL;
	}

	return iReturn;
}

bool CMrConf::MrConfIsValid(char* pszLine)
{
	if (MR_RMRARK != *pszLine) {
		MrConfTrimLeft(pszLine);
		if (0 == strlen(pszLine)) {
			return false;
		}
	}
	else {
		return false;
	}

	return true;
}

bool CMrConf::MrConfIsSection(char* pszLine)
{
	if (MR_SEC_L != *pszLine) {
		return false;
	}

	return true;
}

void CMrConf::MrConfTrim(char* pszLine)
{
	MrConfTrimLeft(pszLine);
	MrConfTrimRight(pszLine);

	return;
}

void CMrConf::MrConfTrimLeft(char* pszLine)
{
	char* pszCur = pszLine;

	while (MR_CTRL_T == *pszCur || MR_CTRL_R == *pszCur || MR_CTRL_N == *pszCur || MR_BLANK == *pszCur) pszCur += 1;
	while ('\0' != (*pszLine ++ = *pszCur ++)) {};

	return;
}

void CMrConf::MrConfTrimRight(char* pszLine)
{
	char* pszCur = pszLine;

	if (strlen(pszLine) > 0) {
		while ('\0' != *pszCur && MR_RMRARK != *pszCur) pszCur += 1;
		*pszCur -- = '\0';
		while (MR_CTRL_T == *pszCur || MR_CTRL_R == *pszCur || MR_CTRL_N == *pszCur || MR_BLANK == *pszCur) pszCur -= 1;
		*(pszCur + 1) = '\0';
	}

	return;
}

int MrConfig(char* pszFile, MRCONFIG_S* pstConf)
{
	CMrConf CConf;
	int iReturn = MR_SUCCESS;

	if (MR_SUCCESS == CConf.MrConfOpen(pszFile)) {
		if (MR_SUCCESS != CConf.MrConfGetVal((char*)"GLOBAL", (char*)"ID", pstConf->m_szID)) {
			iReturn = MR_FAILURE;
		}
		if (MR_SUCCESS != CConf.MrConfGetVal((char*)"MYSQL", (char*)"HOST", pstConf->m_szHost)) {
			iReturn = MR_FAILURE;
		}
		if (MR_SUCCESS != CConf.MrConfGetVal((char*)"MYSQL", (char*)"PORT", pstConf->m_szPort)) {
			iReturn = MR_FAILURE;
		}
		if (MR_SUCCESS != CConf.MrConfGetVal((char*)"MYSQL", (char*)"DBASE", pstConf->m_szDbase)) {
			iReturn = MR_FAILURE;
		}
		if (MR_SUCCESS != CConf.MrConfGetVal((char*)"MYSQL", (char*)"TABLE", pstConf->m_szTable)) {
			iReturn = MR_FAILURE;
		}
		CConf.MrConfClose();
	}
	else {
		iReturn = MR_FAILURE;
	}

	return iReturn;
}
